/**
 * @file app_main.c
 * @brief 应用主函数实现 - MIDI CAN接收与处理
 * @date 2025-11-04
 */

#include "app_main.h"
#include "drv_pwm.h"
#include "drv_can.h"
#include "drv_ad_det.h"
#include "drv_pt100.h"
#include "app_midi.h"
#include "app_midi_stream.h"
#include "sys_manager.h"
#include "sys.h"
#include "stm32f0xx_hal.h"
#include <stdint.h>
#include "user_config.h"

/* 外部变量声明（来自 main.c） */
extern IWDG_HandleTypeDef hiwdg;

/* 私有变量定义 ---------------------------------------------------------*/

#if (FEATURE_DEBUG_CAN_PERIODIC_TEST == 1)
static uint32_t s_last_can_test_time = 0;  /* 上次CAN测试时间 */
#endif

/* 温度监控相关变量 */
#define TEMP_ALARM_INTERVAL_MS      10000   /* 温度报警发送间隔 10秒 */
#define TEMP_THRESHOLD_C            58.0f   /* 温度阈值 58°C */

static uint32_t s_last_temp_alarm_time = 0;    /* 上次温度报警发送时间 */
static bool s_temp_alarm_active = false;       /* 温度报警激活标志 */

/* 私有函数原型声明 -----------------------------------------------*/
static void app_temperature_monitor(void);

/**
 * @brief 应用主函数
 */
void app_main(void)
{
    /* 初始化系统管理器 */
    sys_manager_init();

#if (FEATURE_DEBUG_BYPASS_BOARD_MANAGER == 0)
    /* 初始化 AD_DET 驱动（包含5秒启动延时，自动选择引脚配置） */
    drv_ad_det_init();
#endif

    /* 初始化 CAN 驱动 */
    drv_can_init();

    /* 初始化 PWM 驱动 */
    drv_pwm_init();

    /* 初始化 PT100 温度传感器驱动 */
    drv_pt100_init();

    /* 初始化 MIDI 消息队列和流解析器 */
    app_midi_stream_init();

    /* 初始化 MIDI 应用层 */
    app_midi_init();

    /* 启动系统定时器 (TIM17 1ms中断，用于MIDI状态机) */
    sys_timer_start();

    /* 初始化用户配置 */
    user_config_init();  

    /* 初始化失败时仅记录错误码，不影响状态机运行 */

    /* 发送板卡存在信号 0xBF */
    uint8_t exist_signal = 0xBF;
    drv_can_send(0x100, &exist_signal, 1);

#if (FEATURE_DEBUG_CAN_PERIODIC_TEST == 1)
    /* 初始化CAN测试时间戳 */
    s_last_can_test_time = HAL_GetTick();
#endif
 
    /* 主应用循环 - 基于状态机调度 */
    while (1)
    {
        T_SYSTEM_STATE current_state = sys_manager_get_state();

#if (FEATURE_DEBUG_CAN_PERIODIC_TEST == 1)
        /* 调试模式: 周期性发送0xBF测试CAN */
        uint32_t current_time = HAL_GetTick();
        if ((current_time - s_last_can_test_time) >= FEATURE_DEBUG_CAN_TEST_INTERVAL_MS)
        {
            uint8_t test_signal = 0xBF;
            drv_can_send(0x100, &test_signal, 1);
            s_last_can_test_time = current_time;
        }
#endif

        switch (current_state)
        {
            case SYS_STATE_BOOT:
            {
                /* BOOT模式: 等待板号分配完成（在中断中处理）*/
                if (sys_manager_is_board_assigned())
                {
                    /* 设置MIDI板号 */
                    uint8_t board_id = sys_manager_get_board_id();
                    app_midi_set_board_id(board_id);

                    /* 板号分配完成，切换到播放模式 */
                    sys_manager_set_state(SYS_STATE_PLAYING);
                }

                /* BOOT模式使用更长延时 */
                HAL_Delay(10);
                break;
            }

            case SYS_STATE_PLAYING:
            {
                /* 单条处理CAN消息 -> MIDI队列 */
                can_message_t can_msg;
                if (drv_can_available() && drv_can_read(&can_msg) == 0)
                {
                    app_midi_stream_feed(can_msg.data, can_msg.len);
                }

                /* 单条处理MIDI消息 */
                app_midi_stream_process();

                /* 温度监控（所有播放模式下都需要） */
                app_temperature_monitor();

                /* TODO: 检查是否进入设置模式 */
                /* if (setup_command_received) { sys_manager_set_state(SYS_STATE_SETUP); } */
                break;
            }

            case SYS_STATE_SETUP:
            {
                /* 设定模式: 只处理 CAN/MIDI 消息，忽略其他处理 */
                can_message_t can_msg;
                if (drv_can_available() && drv_can_read(&can_msg) == 0)
                {
                    app_midi_stream_feed(can_msg.data, can_msg.len);
                }
                app_midi_stream_process();  /* 仅处理 MIDI 消息 */
                break;
            }

            default:
            {
                sys_manager_set_state(SYS_STATE_PLAYING);
                break;
            }
        }

        /* 喂看门狗（所有状态都需要） */
#if FEATURE_IWDG_ENABLE
        HAL_IWDG_Refresh(&hiwdg);
#endif

        /* IDLE/PLAYING/SETUP 使用精确1ms时基 */
        if (current_state != SYS_STATE_BOOT)
        {
            HAL_Delay(1);
        }
    }
}

/**
 * @brief 温度监控函数
 * @note 每次循环触发 DMA，检查上次数据是否就绪并处理
 */
static void app_temperature_monitor(void)
{
    /* 触发 DMA 采集（异步，不阻塞） */
    drv_pt100_start_conversion();

    /* 检查上次数据是否就绪 */
    if (!drv_pt100_is_ready()) return;

    float temperature = drv_pt100_get_temperature();
    if (temperature == PT100_TEMP_INVALID) return;

    /* 判断是否超温 */
    if (temperature > TEMP_THRESHOLD_C)
    {
        uint32_t current_time = HAL_GetTick();
        if (!s_temp_alarm_active || (current_time - s_last_temp_alarm_time) >= TEMP_ALARM_INTERVAL_MS)
        {
            uint8_t alarm_msg[3] = {0xB0, 0x0F, 0x7F};
            drv_can_send(0x100, alarm_msg, 3);
            s_last_temp_alarm_time = current_time;
            s_temp_alarm_active = true;
        }
    }
    else
    {
        s_temp_alarm_active = false;
    }
}

/******************************** 文件结束 *********************************/
